const Tag = require('../models/Tag');
const Package = require('../models/Package');
const PackageTag = require('../models/PackageTag');
const { Op } = require('sequelize');

class TagService {
  // 获取所有标签
  async getTags({ page = 1, limit = 50, keyword = '' }) {
    try {
      const offset = (parseInt(page) - 1) * parseInt(limit);
      
      const where = {};
      
      if (keyword) {
        where.name = { [Op.like]: `%${keyword}%` };
      }
      
      const { count, rows } = await Tag.findAndCountAll({
        where,
        order: [['count', 'desc']],
        limit: parseInt(limit),
        offset
      });
      
      return {
        total: count,
        pages: Math.ceil(count / limit),
        currentPage: parseInt(page),
        tags: rows
      };
    } catch (error) {
      console.error('获取标签列表失败:', error);
      throw new Error('获取标签列表失败');
    }
  }

  // 获取标签详情
  async getTagDetail(id) {
    try {
      const tag = await Tag.findByPk(id);
      
      if (!tag) {
        throw new Error('标签不存在');
      }
      
      return tag;
    } catch (error) {
      console.error('获取标签详情失败:', error);
      throw error;
    }
  }

  // 获取标签下的包
  async getPackagesByTag(tagId, { page = 1, limit = 20 }) {
    try {
      const offset = (parseInt(page) - 1) * parseInt(limit);
      
      // 首先检查标签是否存在
      const tag = await Tag.findByPk(tagId);
      if (!tag) {
        throw new Error('标签不存在');
      }
      
      // 查找标签对应的包ID
      const packageTags = await PackageTag.findAll({
        where: { tag_id: tagId },
        attributes: ['package_id'],
        limit: parseInt(limit),
        offset
      });
      
      const packageIds = packageTags.map(pt => pt.package_id);
      
      // 查找包详情
      const packages = await Package.findAll({
        where: {
          id: { [Op.in]: packageIds }
        },
        include: [{ model: Tag, as: 'tags', through: { attributes: [] } }]
      });
      
      // 获取总数量
      const total = await PackageTag.count({ where: { tag_id: tagId } });
      
      return {
        total,
        pages: Math.ceil(total / limit),
        currentPage: parseInt(page),
        packages
      };
    } catch (error) {
      console.error('获取标签下的包失败:', error);
      throw new Error('获取标签下的包失败');
    }
  }

  // 获取标签排行榜
  async getTagLeaderboard(limit = 50) {
    try {
      const tags = await Tag.findAll({
        order: [['count', 'desc']],
        limit
      });
      
      return tags;
    } catch (error) {
      console.error('获取标签排行榜失败:', error);
      throw new Error('获取标签排行榜失败');
    }
  }

  // 获取标签下的包排行榜
  async getPackageLeaderboardByTag(tagId, limit = 50) {
    try {
      // 查找标签对应的包
      const packageTags = await PackageTag.findAll({
        where: { tag_id: tagId },
        attributes: ['package_id']
      });
      
      const packageIds = packageTags.map(pt => pt.package_id);
      
      const packages = await Package.findAll({
        where: {
          id: { [Op.in]: packageIds }
        },
        order: [['downloads', 'desc']],
        limit,
        attributes: ['id', 'name', 'description_zh', 'downloads', 'score']
      });
      
      return packages;
    } catch (error) {
      console.error('获取标签下的包排行榜失败:', error);
      throw new Error('获取标签下的包排行榜失败');
    }
  }

  // 添加标签到包
  async addTagToPackage(packageId, tagName) {
    try {
      // 查找或创建标签
      let tag = await Tag.findOne({ where: { name: tagName } });
      
      if (!tag) {
        tag = await Tag.create({ name: tagName, count: 0 });
      }
      
      // 检查关联是否已存在
      const existingRelation = await PackageTag.findOne({
        where: {
          package_id: packageId,
          tag_id: tag.id
        }
      });
      
      if (!existingRelation) {
        // 创建关联
        await PackageTag.create({
          package_id: packageId,
          tag_id: tag.id
        });
        
        // 更新标签计数
        tag.count += 1;
        await tag.save();
      }
      
      return tag;
    } catch (error) {
      console.error('添加标签到包失败:', error);
      throw new Error('添加标签到包失败');
    }
  }

  // 创建标签
  async createTag(tagData) {
    try {
      const tag = await Tag.create({
        ...tagData,
        count: 0
      });
      
      return tag;
    } catch (error) {
      console.error('创建标签失败:', error);
      throw new Error('创建标签失败');
    }
  }

  // 更新标签
  async updateTag(id, tagData) {
    try {
      const tag = await Tag.findByPk(id);
      if (!tag) {
        throw new Error('标签不存在');
      }
      
      await tag.update(tagData);
      return tag;
    } catch (error) {
      console.error('更新标签失败:', error);
      throw error;
    }
  }

  // 删除标签
  async deleteTag(id) {
    try {
      const tag = await Tag.findByPk(id);
      if (!tag) {
        throw new Error('标签不存在');
      }
      
      // 删除相关的包标签关联
      await PackageTag.destroy({ where: { tag_id: id } });
      
      await tag.destroy();
      return { message: '删除成功' };
    } catch (error) {
      console.error('删除标签失败:', error);
      throw error;
    }
  }

  // 从包中移除标签
  async removeTagFromPackage(packageId, tagId) {
    try {
      // 删除关联
      const deleted = await PackageTag.destroy({
        where: {
          package_id: packageId,
          tag_id: tagId
        }
      });
      
      if (deleted > 0) {
        // 更新标签计数
        const tag = await Tag.findByPk(tagId);
        if (tag) {
          tag.count = Math.max(0, tag.count - 1);
          await tag.save();
        }
      }
      
      return { deleted };
    } catch (error) {
      console.error('从包中移除标签失败:', error);
      throw new Error('从包中移除标签失败');
    }
  }
}

module.exports = new TagService();